#include <iostream>
using namespace std;

//class Person {
//public:
//	virtual ~Person() {cout << "~Person()" << endl;}
//};
//
//class Student : public Person {
//public:
//	virtual ~Student() { cout << "~Student()" << endl; }
//};
//
///*只有派生类Student的析构函数重写了Person的析构函数，下面的delete对象调用
//析构函数，才能构成多态，才能保证p1和p2指向的对象正确的调用析构函数。*/
//int main()
//{
//	Person* p1 = new Person;
//	Person* p2 = new Student;
//	delete p1;
//	delete p2;
//	return 0;
//}

//class Car //抽象类
//{
//public:
//	virtual void Drive() = 0; //纯虚函数
//  void func(){
//    cout << "func()" << endl;
//  };
//};
//
//class Benz :public Car
//{
//public:
//	virtual void Drive() //派生类必须重写
//	{
//		cout << "Benz-舒适" << endl;
//	}
//};
//
//class BMW :public Car
//{
//public:
//	virtual void Drive() //派生类必须重写
//	{
//		cout << "BMW-操控" << endl;
//	}
//};
//
//void Func(Car &car){
//  car.Drive();
//}
//
//int main(){
//  Benz bc;
//  BMW bm;
//  Func(bc);
//  Func(bm);
//  bc.func();
//  return 0;
//}

//class Person{
//  virtual void Buyticket(){
//    cout << "Person::Buyticket()" << endl;
//  }
//  virtual void Func1(){
//    cout << "Person::Func1()" << endl;
//  }
//};
//
//class Student:public Person{
//  virtual void Buyticket(){
//    cout << "Student::Buyticket()" << endl;
//  }
//  virtual void Func2(){
//    cout << "Student::Func2()" << endl;
//  }
//};
//
typedef void(*VFPTR)();

void PrintVFTable(VFPTR *table, size_t n){
  for(size_t i = 0; i<n; ++i)
  {
    printf("vftable[%lu]:%p -> ", i, table[i]);
    table[i](); 
  }
}
//
//int main(){
//  Person p;
//  Person p1;
//  Student s;
//  Student s1;
//
//  cout << "p: " << (VFPTR*)*(long long*)&p << endl; 
//  cout << "p1: " << (VFPTR*)*(long long*)&p1 << endl; 
//  cout << "s: " << (VFPTR*)*(long long*)&s << endl; 
//  cout << "s1: " << (VFPTR*)*(long long*)&s1 << endl; 
//  cout << endl;
//
//  PrintVFTable((VFPTR*)*(long long*)&p,2);
//  cout << endl;
//  PrintVFTable((VFPTR*)*(long long*)&s,3);
//  return 0;
//}

class Base1{
  virtual void Func1(){
    cout << "Base1::Func1()" << endl;
  }
  virtual void Func2(){
    cout << "Base1::Func2()" << endl;
  }
};

class Base2{
  virtual void Func1(){
    cout << "Base2::Func1()" << endl;
  }
  virtual void Func2(){
    cout << "Base2::Func2()" << endl;
  }
};

class Derive:public Base1, public Base2{
public:
  virtual void Func1(){
    cout << "Derive::Func1()" << endl;
  }
  virtual void Func2(){
    cout << "Derive::Func2()" << endl;
  }
  virtual void Func3(){
    cout << "Derive::Func3()" << endl;
  }
};

void Test1(){
  Derive d;
  Base1 *pb1 = &d;
  Base2 *pb2 = &d;
  PrintVFTable((VFPTR*)*(long long*)pb1, 3);
  cout << endl;
  PrintVFTable((VFPTR*)*(long long*)pb2, 2);
  cout << endl;
}

void Test2(){
  Derive d;
  PrintVFTable((VFPTR*)*(long long*)&d, 3);
  cout << endl;
  PrintVFTable((VFPTR*)*(long long*)((char*)&d+sizeof(Base1)), 2);
}

int main(){
  Test1();
  Derive d;
  d.Func1();
  d.Func2();
  d.Func3();
  return 0;
}
